﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using Frame.Global;
using DevExpress.Web.ASPxEditors;

namespace Frame.Pages
{
    public enum ActionType
    {
        New, Update
    }
    public abstract class DetailEditPage : BasePage
    {
        protected DevExpress.Web.ASPxRoundPanel.ASPxRoundPanel Detailpanel;
        protected DevExpress.Web.ASPxEditors.ASPxButton SubmitBtn;
        protected DataContext DataSession = GlobalRunParms.GetDefaultDataContext();
        protected ActionType ModelAction
        {
            get
            {
                if (Request.QueryString["KeyID"] != null)
                {
                    return ActionType.Update;
                }
                else
                {
                    return ActionType.New;
                }
            }
        }
        protected string KeyID
        {
            get
            {
                return Request.QueryString["KeyID"];
            }
        }
        /// <summary>
        /// 实例对象
        /// </summary>
        protected abstract object Model
        {
            get;
        }

        protected abstract string ScriptBackUrl
        {
            get;
        }

        #region 方法 事件
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            SubmitBtn.Click += new EventHandler(SubmitBtn_Click);
            DataMapping(this.Page, Model);
        }
        protected virtual void SubmitBtn_Click(object sender, EventArgs e)
        {
            try
            {
                string msg;
                if (ModelAction == ActionType.New)
                {
                    DataSession.GetTable(Model.GetType()).InsertOnSubmit(Model);
                    msg = "新增成功！";
                }
                else
                {
                    msg = "修改成功！";
                }
                DataSession.SubmitChanges();
                Global.GlobalFunctions.AlertToUrl(msg, ScriptBackUrl);
            }
            catch (Exception ex)
            {
                Global.GlobalFunctions.AlertToUrl(string.Format("操作发生错误{0}，请稍后重试！",ex.Message), ScriptBackUrl);
            }
            
        }
        /// <summary>
        /// 使用反射的映射函数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="page"></param>
        /// <param name="Model"></param>
        private void DataMapping(System.Web.UI.Page page, object Model)
        {

            System.Reflection.PropertyInfo[] proinfoary = Model.GetType().GetProperties();
            foreach (System.Reflection.PropertyInfo property in proinfoary)
            {
                DevExpress.Web.ASPxEditors.ASPxEdit editor =
                    (DevExpress.Web.ASPxEditors.ASPxEdit)Detailpanel.FindControl(string.Format("Edit_{0}", property.Name));
                if (editor != null)
                {
                    if (page.IsPostBack || page.IsCallback)
                    {
                        object objValue;
                        if (property.PropertyType == typeof(Int32) || property.PropertyType == typeof(Int32?))
                        {
                            objValue = Convert.ToInt32(editor.Value);
                        }
                        else if (property.PropertyType == typeof(Int64) || property.PropertyType == typeof(Int64?))
                        {
                            objValue = Convert.ToInt64(editor.Value);
                        }
                        else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal?))
                        {
                            objValue = Convert.ToDecimal(editor.Value);
                        }
                        else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?))
                        {
                            objValue = Convert.ToDateTime(editor.Value);
                        }
                        else
                        {
                            objValue = editor.Value;
                        }

                        property.SetValue(Model, objValue, null);
                    }
                    else
                    {
                        if (this.ModelAction != ActionType.New)
                        {
                            editor.Value = property.GetValue(Model, null);
                        }

                    }
                }
            }
        }

        #endregion

    }

    /// <summary>
    /// 详细页编辑管理页接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IDetailEditManPage<T>
    {
        T Model
        {
            set;
            get;
        }
        string BackUrl
        {
            set;
            get;
        }
        string ScriptBackUrl
        {
            get;
            set;
        }

    }

    public class RefrenceContext<T>:IDetailEditManPage<T>
    {
        private RefrenceContext()
        {
        }

        #region IDetailEditManPage<T> 成员

        public T Model
        {
            get;
            set;
        }

        public string BackUrl
        {
            get;
            set;
        }

        public string ScriptBackUrl
        {
            get;
            set;
        }

        #endregion

        public static RefrenceContext<T> Current
        {
            get
            {
                System.Web.UI.Page page = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler;
                if (page.Session[string.Format("{0}_#*Model", typeof(T).Name)] != null)
                {
                    RefrenceContext<T> obj =
                            page.Session[string.Format("{0}_#*Model", typeof(T).Name)] as RefrenceContext<T>;
                    if (obj != null)
                    {
                        return obj;
                    }
                    else
                    {
                        return null;
                    }
                }
                else if (System.Web.HttpContext.Current.Handler != null && System.Web.HttpContext.Current.Handler is IDetailEditManPage<T>)
                {
                    if ((page as IDetailEditManPage<T>).Model!=null)
                    {
                        page.Session[string.Format("{0}_#*Model", typeof(T).Name)] = RefrenceContext<T>.Copy(page as IDetailEditManPage<T>);
                        return page.Session[string.Format("{0}_#*Model", typeof(T).Name)] as RefrenceContext<T>;
                    }
                    else
                    {
                        return null;
                    }
                    
                }
                else
                {
                    return null;
                }

            }
        }

        public static void UpdateCurrent(IDetailEditManPage<T> NewContext)
        {
            System.Web.UI.Page page = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler;
            page.Session[string.Format("{0}_#*Model", typeof(T).Name)] = RefrenceContext<T>.Copy(NewContext);
        }

        public static RefrenceContext<T> Copy(IDetailEditManPage<T> Source)
        {
            RefrenceContext<T> newone = new RefrenceContext<T>();
            newone.BackUrl = Source.BackUrl;
            newone.ScriptBackUrl = Source.ScriptBackUrl;
            newone.Model = Source.Model;
            return newone;
        }

        public static void Clear()
        {
            System.Web.UI.Page page = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler;
            page.Session[string.Format("{0}_#*Model", typeof(T).Name)] = null;
        }


    }


    public abstract class DetailEditPage<T> : BasePage where T : class , new()
    {
        protected DevExpress.Web.ASPxRoundPanel.ASPxRoundPanel Detailpanel;
        protected DevExpress.Web.ASPxEditors.ASPxButton SubmitBtn;
        protected DataContext DataSession = GlobalRunParms.GetDefaultDataContext();
        protected ActionType ModelAction
        {
            get
            {
                IDetailEditManPage<T> ModelSource = Context.Handler as IDetailEditManPage<T>;
                if (ModelSource != null)
                {

                    return ActionType.Update;
                }
                else
                {
                    return ActionType.New;
                }
            }
        }

        T m_Model;
        /// <summary>
        /// 实例对象
        /// </summary>
        protected T Model
        {
            get
            {
                if (m_Model == null)
                {
                    IDetailEditManPage<T> ModelSource = Context.Handler as IDetailEditManPage<T>;
                    if (ModelSource != null)
                    {
                        m_Model = ModelSource.Model;
                    }
                    else
                    {
                        m_Model = new T();
                    }
                }
                return m_Model;

            }
        }

        #region 方法 事件
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            SubmitBtn.Click += new EventHandler(SubmitBtn_Click);
            DataMapping(this.Page, Model);
        }
        void SubmitBtn_Click(object sender, EventArgs e)
        {
            if (ModelAction == ActionType.New)
            {
                DataSession.GetTable<T>().InsertOnSubmit(Model);
            }
            DataSession.SubmitChanges();
        }
        /// <summary>
        /// 使用反射的映射函数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="page"></param>
        /// <param name="Model"></param>
        private void DataMapping(System.Web.UI.Page page, object Model)
        {

            System.Reflection.PropertyInfo[] proinfoary = Model.GetType().GetProperties();
            foreach (System.Reflection.PropertyInfo property in proinfoary)
            {
                DevExpress.Web.ASPxEditors.ASPxEdit editor =
                    (DevExpress.Web.ASPxEditors.ASPxEdit)Detailpanel.FindControl(string.Format("Edit_{0}", property.Name));
                if (editor == null)
                {
                    break;
                }
                if (page.IsPostBack || page.IsCallback)
                {
                    object objValue;
                    if (property.PropertyType == typeof(Int32))
                    {
                        objValue = Convert.ToInt32(editor.Value);
                    }
                    else if (property.PropertyType == typeof(Int64))
                    {
                        objValue = Convert.ToInt64(editor.Value);
                    }
                    else if (property.PropertyType == typeof(decimal))
                    {
                        objValue = Convert.ToDecimal(editor.Value);
                    }
                    else if (property.PropertyType == typeof(DateTime))
                    {
                        objValue = Convert.ToDateTime(editor.Value);
                    }
                    else
                    {
                        objValue = editor.Value;
                    }

                    property.SetValue(Model, objValue, null);
                }
                else
                {
                    if (this.ModelAction != ActionType.New)
                    {
                        editor.Value = property.GetValue(Model, null);
                    }

                }
            }
        }

        #endregion

    }
}
